import threading
import time
import datetime
import os
import re
import MySQLdb
import sys
import struct
import traceback
#count = 0  

class Monitor(threading.Thread):  
    def __init__(self,vmipath,vmuuid,vmname,interestinglist,threadName):  
        super(Monitor, self).__init__(name = threadName)  
        self.vmipath = vmipath
        self.vmuuid = vmuuid
        self.vmname = vmname
        self.interestinglist = interestinglist
      
    def run(self):  
             
        #print "Thread is running......\n"
	try:
            os.system(self.vmipath+r"/process-list " + self.vmname + " -a > temp.txt")
        except:
            return None
        conn = MySQLdb.connect(host=monitor_db_ip,user=DB_user,passwd=DB_passwd,db= DB_name)#the database is located on the web controller's machine 
        cursor = conn.cursor()
      	
	fo = open("temp.txt", "r")
	try:
	    while 1:
	    	line = fo.readline()
	    	if not line:#end of file
	    	    break
				
	    #	res_pid=re.search(r'\[\s*(\d*)\s*\]\s*(\d*)',line,0)
	    	res_depline=re.search(r'\[\s*(\d*)\s*\]\s*(\S*)\s*(\d*)\s*(\d*)\s*(\d*)\s*(\d*)\s*(\d*)',line,0)		
	    	try:
        	    pid=res_depline.group(1)
		    pname=res_depline.group(2)
		    cpu_time=res_depline.group(3)
		    memory=res_depline.group(4)
		    maxmemory=res_depline.group(5)
		    readop=res_depline.group(6)
		    writeop=res_depline.group(7)
		    #print pid,pname,cpu_time,memory,maxmemory,readop,writeop
		    
		    values = [self.vmuuid,self.vmname,pid,pname,cpu_time,memory,maxmemory,readop,writeop,datetime.datetime.now()]
		    # judge if the process is on the list of interesting,like oracle.exe....
		    #if self.interestinglist.count(pname) > 0:
                    #print pid,pname,cpu_time,memory,maxmemory,readop,writeop
                    if pid == "0":
                        break
                    print pid,pname,cpu_time,memory,maxmemory,readop,writeop
                    cursor.execute('insert into proc_info values(null,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)',values)
		except:
		    continue
	    print '***************',self.vmname,'*************'
	    conn.commit()
            cursor.close()
            conn.close()	
	except Exception,e:
	    print traceback.format_exc() 
	
	fo.close()
	
def monitorProc(vmipath,vmuuid,vmname):
    start = datetime.datetime.now()
    try:
        os.system(vmipath+r"/process-list " + vmname + " -a > temp.txt")
    except:
        return None
      	
    fo = open("temp.txt", "r")
    try:
        while 1:
            line = fo.readline()
	    if not line:#end of file
	    	break
				
	    #	res_pid=re.search(r'\[\s*(\d*)\s*\]\s*(\d*)',line,0)
	    res_depline=re.search(r'\[\s*(\d*)\s*\]\s*(\S*)\s*(\d*)\s*(\d*)\s*(\d*)\s*(\d*)\s*(\d*)',line,0)		
	    try:
        	pid=res_depline.group(1)
		pname=res_depline.group(2)
	        cpu_time=res_depline.group(3)
                memory=res_depline.group(4)
	        maxmemory=res_depline.group(5)
	        readop=res_depline.group(6)
	        writeop=res_depline.group(7)
		    #print pid,pname,cpu_time,memory,maxmemory,readop,writeop
		    
	        #values = [self.vmuuid,pid,pname,cpu_time,memory,maxmemory,readop,writeop,datetime.datetime.now()]
		    # judge if the process is on the list of interesting,like oracle.exe....
		    #if self.interestinglist.count(pname) > 0:
                    #print pid,pname,cpu_time,memory,maxmemory,readop,writeop
                if pid == "0":
                    break
                print pid,pname,cpu_time,memory,maxmemory,readop,writeop
                item = [vmuuid,vmname,pid,pname,cpu_time,memory,maxmemory,readop,writeop,datetime.datetime.now()]
                value.append(item)
                #cursor.execute('insert into proc_info values(null,%s,%s,%s,%s,%s,%s,%s,%s,%s)',values)
	    except:
		continue
	print '***************',vmname,'*************'
	#conn.commit()
        #cursor.close()
        #conn.close()	
    except Exception,e:
	print traceback.format_exc() 
	
    fo.close()
    end = datetime.datetime.now()
    print 'process rans ',(end-start),' seconds.'
    
def updateVmName():
	
    os.system("xe vm-list>temp.txt")	
    fo = open("temp.txt", "r")
	
    while 1:
    	line = fo.readline()
    	if not line:#end of file
    	    break
			
    	res_vmuuid=re.search(r'uuid \( RO\)\s*: (\S*)',line,0)	
    	if not res_vmuuid:# it is not an external_ids line
    	    continue
			
    	vmuuid=res_vmuuid.group(1)
    	line = fo.readline()
    	if not line:#end of file
    	    break
    	res_vmuuid=re.search(r'name-label \( RW\): (\S*)',line,0)	
    	if not res_vmuuid:# it is not an external_ids line
    	    continue
    	name=res_vmuuid.group(1)
    	if name.startswith('i') == False:
            continue
    	flag = 0
    	for item in vmname:
            if item[0] == vmuuid:
                flag = 1
                break
            
    	if flag==0 :
    	    vmname.append([vmuuid,name])
    	else:
    	    continue
#   	print "vmuuid:",vmuuid
	
    fo.close()
    
def writeConf():
    fo = open("/etc/libvmi.conf","w")
    try:
    	for item in vmname:
	    fo.write(item[1]+' {ostype = "Windows";win_tasks = 0x88;win_pdbase = 0x18;win_pid = 0x84;} '+'\n')
    except:
	print "write operation failed!"
    fo.close()
	
while 1:
    start = datetime.datetime.now()
    
    global conf_value #get the monitor module database IP, user name, password and database name from the configuration file "monitor_db_conf.txt"
    global monitor_db_ip
    global DB_user
    global DB_passwd
    global DB_name
    conf_value=[]
    
    fo = open("monitor_db_conf.txt", "r")
    try:
        while 1:
            
            line = fo.readline().strip('\n')
            
            if not line:#end of file
                break
            conf_value.append(line) 
    except Exception,e:
        print traceback.format_exc() 
    fo.close()
    
    monitor_db_ip=conf_value[0]
    DB_user=conf_value[1]
    DB_passwd=conf_value[2]
    DB_name=conf_value[3]
    
    global vmname
    vmname = []
    ###vmname = [['8b945802-b426-360a-e3ec-9b0d7ec9e0af','clonexp1'],['2d9d3fa4-6d9b-1d3f-3a94-5247dd8c0f32','xp1'],['9287230e-ab5c-2c95-3ae3-1b23a76a5c69','xp2']]
    updateVmName()
    writeConf()
    global value
    value = [] 
    vmipath=r"/root/vmi/libvmi-0.8/examples"
    interestinglist = ['explorer.exe']
    for item in vmname:
        try:
            monitorProc(vmipath,item[0],item[1])
        except:
            print "the vm ",item[1]," is not running now."
            continue
    #print "All threads have stopped."
    conn = MySQLdb.connect(host=monitor_db_ip,user=DB_user,passwd=DB_passwd,db= DB_name)#the database is located on the web controller's machine 
    cursor = conn.cursor()
    cursor.executemany('insert into proc_info values(null,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)',value)
    conn.commit()
    cursor.close()
    conn.close()
    end = datetime.datetime.now()
    print 'process rans ',(end-start),' seconds.'
    time.sleep(10)
    